package com.digua.atools.tools;


import com.alibaba.fastjson.JSON;
import com.blankj.utilcode.util.EncryptUtils;
import com.digua.atools.tools.listener.ToStrListener;

import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.List;

/**
 * @author:digua
 * @dat:2021/8/21
 * @description:字符串工具类
 */
public class StrUtil {
    public final static String separator = ",";

    /**
     * 格式化字符串
     *
     * @param format 占位符只能为%s或{}
     * @param params
     * @return
     */
    public static String format(String format, Object... params) {
        return formatByArr(format, params);
    }

    /**
     * 格式化字符串
     *
     * @param format 占位符只能为%s或{}
     * @param params
     * @return
     */
    public static String formatByArr(String format, Object[] params) {
        if (isBlank(format) || params == null || params.length <= 0) {
            return format;
        }
        if (format.indexOf("%s") >= 0) {
            format = format.replaceAll("%s", "{}");
        }
        int formatLength = format.length();
        StringBuilder sbuf = new StringBuilder(formatLength + 50);
        int handledPosition = 0;
        for (int argIndex = 0; argIndex < params.length; ++argIndex) {
            int delimIndex = format.indexOf("{}", handledPosition);
            if (delimIndex == -1) {
                if (handledPosition == 0) {
                    return format;
                }
                sbuf.append(format, handledPosition, formatLength);
                return sbuf.toString();
            }
            if (delimIndex > 0 && format.charAt(delimIndex - 1) == '\\') {
                if (delimIndex > 1 && format.charAt(delimIndex - 2) == '\\') {
                    sbuf.append(format, handledPosition, delimIndex - 1);
                    sbuf.append(utf8Str(params[argIndex]));
                    handledPosition = delimIndex + 2;
                } else {
                    --argIndex;
                    sbuf.append(format, handledPosition, delimIndex - 1);
                    sbuf.append('{');
                    handledPosition = delimIndex + 1;
                }
            } else {
                sbuf.append(format, handledPosition, delimIndex);
                sbuf.append(utf8Str(params[argIndex]));
                handledPosition = delimIndex + 2;
            }
        }
        sbuf.append(format, handledPosition, format.length());
        return sbuf.toString();
    }

    /**
     * 将Object转成UTF-8类型字符串
     *
     * @param obj
     * @return
     */
    private static String utf8Str(Object obj) {
        return str(obj, Charset.forName("UTF-8"));
    }

    /**
     * 将Object转成字符串
     *
     * @param obj
     * @param charset Charset.forName("类型名")
     * @return
     */
    public static String str(Object obj, Charset charset) {
        if (null == obj) {
            return null;
        } else if (obj instanceof String) {
            return (String) obj;
        } else if (obj instanceof byte[]) {
            return str((byte[]) ((byte[]) obj), charset);
        } else if (obj instanceof Byte[]) {
            return str((Byte[]) ((Byte[]) obj), charset);
        } else if (obj instanceof ByteBuffer) {
            return str((ByteBuffer) obj, charset);
        } else {
            return null != obj && obj.getClass().isArray() ? JSON.toJSONString(obj) : obj.toString();
        }
    }

    /**
     * 判断str1中是否包含str2 忽略大小写
     *
     * @param str1
     * @param str2
     * @return
     */
    public static boolean containsIgnoreCase(String str1, String str2) {
        if (isBlank(str1) || isBlank(str2)) {
            return false;
        }
        return contains(str1.toLowerCase(), str2.toLowerCase());
    }

    /**
     * 判断str1中是否包含str2
     *
     * @param str1
     * @param str2
     * @return
     */
    public static boolean contains(String str1, String str2) {
        if (isBlank(str1) || isBlank(str2)) {
            return false;
        }
        return str1.contains(str2);
    }

    /**
     * 判断str1中是否包含str2 忽略大小写
     *
     * @param str
     * @param strs
     * @return
     */
    public static boolean containsIgnoreCase(String str, String... strs) {
        if (isBlank(str) || strs == null || strs.length <= 0) {
            return false;
        }
        String[] arr = new String[strs.length];
        for (int i = 0; i < strs.length; i++) {
            arr[i] = isBlank(strs[i]) ? strs[i] : strs[i].toLowerCase();
        }
        return contains(str.toLowerCase(), arr);
    }

    /**
     * 判断str1中是否包含str2
     *
     * @param str
     * @param strs
     * @return
     */
    public static boolean contains(String str, String... strs) {
        if (isBlank(str) || strs == null || strs.length <= 0) {
            return false;
        }
        for (String s : strs) {
            if (contains(str, s)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 集合拼接
     *
     * @param list 集合
     * @return
     */
    public static String join(List list) {
        return join(list, separator);
    }

    /**
     * 集合拼接
     *
     * @param list      集合
     * @param separator 分割符
     * @return
     */
    public static <T> String join(List<T> list, String separator) {
        return join(list, separator, null);
    }

    /**
     * 集合拼接
     *
     * @param list     集合
     * @param listener 对象转字符串
     * @return
     */
    public static <T> String join(List<T> list, ToStrListener<T> listener) {
        return join(list, separator, listener);
    }

    /**
     * 集合拼接
     *
     * @param list      集合
     * @param separator 分割符
     * @param listener  对象转字符串
     * @return
     */
    public static <T> String join(List<T> list, String separator, ToStrListener<T> listener) {
        if (com.digua.atools.tools.CollUtil.isBlank(list)) {
            return "";
        }
        String res = "";
        if (listener != null) {
            for (T data : list) {
                res += listener.toStr(data) + separator;
            }
        } else {
            for (T data : list) {
                res += data.toString() + separator;
            }
        }
        return res.substring(0, res.length() - separator.length());
    }

    /**
     * 数组拼接
     *
     * @param arr 数组
     * @return
     */
    public static <T> String join(T[] arr) {
        return join(arr, separator);
    }

    /**
     * 数组拼接
     *
     * @param arr       数组
     * @param separator 分割符
     * @return
     */
    public static <T> String join(T[] arr, String separator) {
        return join(arr, separator, null);
    }

    /**
     * 数组拼接
     *
     * @param arr      数组
     * @param listener 对象转字符串
     * @return
     */
    public static <T> String join(T[] arr, ToStrListener<T> listener) {
        return join(arr, separator, listener);
    }

    /**
     * 数组拼接
     *
     * @param arr       数组
     * @param separator 分割符
     * @param listener  对象转字符串
     * @return
     */
    public static <T> String join(T[] arr, String separator, ToStrListener<T> listener) {
        if (arr == null || arr.length <= 0) {
            return "";
        }
        String res = "";
        if (listener != null) {
            for (T data : arr) {
                String val = listener.toStr(data);
                if (val == null) {
                    continue;
                }
                res += val + separator;
            }
        } else {
            for (T data : arr) {
                if (data == null) {
                    continue;
                }
                res += data.toString() + separator;
            }
        }
        return isBlank(res) ? res : res.substring(0, res.length() - separator.length());
    }

    /**
     * 判断是否全部为空字符串
     *
     * @param str
     * @return
     */
    public static boolean allBlank(String... str) {
        if (str == null || str.length == 0) {
            return true;
        }
        for (String s : str) {
            if (isNotBlank(s)) {
                return false;
            }
        }
        return true;
    }

    /**
     * 判断是否有空字符串
     *
     * @param str
     * @return
     */
    public static boolean hasBlank(String... str) {
        if (str == null || str.length == 0) {
            return true;
        }
        for (String s : str) {
            if (isBlank(s)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 判断是否没有空字符串
     *
     * @param str
     * @return
     */
    public static boolean hasNotBlank(String... str) {
        return !hasBlank(str);
    }

    /**
     * 判断是否是空字符串
     *
     * @param str
     * @return
     */
    public static boolean isBlank(String str) {
        return str == null || str.trim().length() == 0;
    }

    /**
     * 判断是否是非空字符串
     *
     * @param str
     * @return
     */
    public static boolean isNotBlank(String str) {
        return !isBlank(str);
    }

    /**
     * 字符串去空
     *
     * @param str
     * @return
     */
    public static String trim(String str) {
        return str == null ? null : isBlank(str) ? "" : str.trim();
    }

    /**
     * 获取非空值
     *
     * @param val    原值
     * @param defVal 默认值
     * @return 如没有默认值，val为空时返回：“”；如果有默认值时，为空返回默认值
     */
    public static String getVal(String val, String... defVal) {
        return isNotBlank(val) ? val : defVal == null || defVal.length <= 0 ? "" : defVal[0];
    }

    /**
     * 获取网络请求地址
     *
     * @param head
     * @param content
     * @return
     */
    public static String getNetUrl(String head, String... content) {
        String url = "";
        if (content != null && content.length >= 0) {
            url = join(content, "");
        }
        if (isNetUrl(url)) {
            return url;
        }
        if (!isNetUrl(head)) {
            return "";
        }
        String separator = head.endsWith("/") || head.endsWith("\\") || isBlank(url) ? "" : "/";
        return head + separator + url;
    }

    /**
     * 是否是网络请求地址
     *
     * @param url
     * @return
     */
    public static boolean isNetUrl(String url) {
        return contains(url, "://");
    }

    /**
     * 获取指定长度的占位符
     *
     * @param len         长度
     * @param placeholder 占位符
     * @return
     */
    public static String getPlaceholder(int len, String placeholder) {
        if (len <= 0 || isBlank(placeholder)) {
            return "";
        }
        String res = "";
        for (int i = 0; i < len; i++) {
            res += placeholder;
        }
        return res;
    }

    /**
     * MD5加密
     *
     * @param str 加密内容
     * @return
     */
    public static String md5(String str) {
        if (isBlank(str)) {
            return str;
        }
        return EncryptUtils.encryptMD5ToString(str);
    }
}
